package com.shop.cloud.upms.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.shop.cloud.common.core.constant.CommonConstants;
import com.shop.cloud.common.data.tenant.TenantContextHolder;
import com.shop.cloud.common.sms.config.SmsConfigProperties;
import com.shop.cloud.common.sms.util.SmsUtils;
import com.shop.cloud.upms.admin.mapper.SysUserMapper;
import com.shop.cloud.upms.admin.service.PhoneService;
import com.shop.cloud.upms.admin.service.SysConfigSmsService;
import com.shop.cloud.upms.common.entity.SysConfigSms;
import com.shop.cloud.upms.common.entity.SysConfigSmsTemplates;
import com.shop.cloud.upms.common.entity.SysUser;
import com.shop.cloud.common.core.constant.CacheConstants;
import com.shop.cloud.common.core.constant.SecurityConstants;
import com.shop.cloud.common.core.util.R;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;

/**
 * @author
 * <p>
 * 手机登录相关业务实现
 */
@Slf4j
@Service
@AllArgsConstructor
public class PhoneServiceImpl implements PhoneService {
	private final RedisTemplate redisTemplate;
	private final SysUserMapper userMapper;
	private final SysConfigSmsService sysConfigSmsService;

	/**
	 * 发送手机验证码
	 *
	 * @param phone
	 * @param type
	 * @return code
	 */
	@SneakyThrows
	@Override
	public R<Boolean> sendSmsCode(String phone, String type, String graphCode) {
		//校验图形码
		String graphCodeKey = CacheConstants.VER_CODE_DEFAULT + phone;
		if (!redisTemplate.hasKey(graphCodeKey)) {
			return R.failed("图形验证码不合法");
		}
		Object graphCodeObj = redisTemplate.opsForValue().get(graphCodeKey);
		redisTemplate.delete(graphCodeKey);
		if (graphCodeObj == null) {
			return R.failed("图形验证码不合法");
		}
		String saveGraphCode = graphCodeObj.toString();
		if (StrUtil.isBlank(saveGraphCode)) {
			redisTemplate.delete(graphCodeKey);
			return R.failed("图形验证码不合法");
		}
		if (!StrUtil.equals(saveGraphCode, graphCode)) {
			return R.failed("图形验证码不合法");
		}

		String signName = null;
		String templateCode = null;
		SmsConfigProperties smsConfigProperties = new SmsConfigProperties();
		if(CommonConstants.PHONE_CODE_1.equals(type) || CommonConstants.PHONE_CODE_2.equals(type)){
			SysUser sysUser = new  SysUser();
			sysUser.setPhone(phone);
			sysUser = userMapper.getByNoTenant(sysUser);
			//1、登录
			if(CommonConstants.PHONE_CODE_1.equals(type)){
				if (sysUser == null) {
					log.info("手机号未注册:{}", phone);
					return R.failed(Boolean.FALSE, "该手机号未绑定任何账号");
				}else{
					TenantContextHolder.setTenantId(sysUser.getTenantId());
				}
				SysConfigSmsTemplates sysConfigSmsTemplates = this.getSysConfigSmsTemplates(smsConfigProperties);
				signName = sysConfigSmsTemplates.getSignName1();
				templateCode = sysConfigSmsTemplates.getTemplateCode1();
			}
			//2、绑定手机号/注册
			if(CommonConstants.PHONE_CODE_2.equals(type)){
				if (sysUser != null) {
					log.info("手机号已被注册:{}", phone);
					return R.failed(Boolean.FALSE, "该手机号已被其他账号绑定");
				}
				SysConfigSmsTemplates sysConfigSmsTemplates = this.getSysConfigSmsTemplates(smsConfigProperties);
				signName = sysConfigSmsTemplates.getSignName2();
				templateCode = sysConfigSmsTemplates.getTemplateCode2();
			}
		}else{
			if(CommonConstants.PHONE_CODE_3.equals(type)){
				SysConfigSmsTemplates sysConfigSmsTemplates = this.getSysConfigSmsTemplates(smsConfigProperties);
				//3、解绑手机
				signName = sysConfigSmsTemplates.getSignName3();
				templateCode = sysConfigSmsTemplates.getTemplateCode3();
			}else if(CommonConstants.PHONE_CODE_5.equals(type)){
				SysConfigSmsTemplates sysConfigSmsTemplates = this.getSysConfigSmsTemplates(smsConfigProperties);
				//5、店铺入驻手机号码验证码
				signName = sysConfigSmsTemplates.getSignName6();
				templateCode = sysConfigSmsTemplates.getTemplateCode6();
			}else if(CommonConstants.PHONE_CODE_6.equals(type)){
				//取系统平台短信配置
				TenantContextHolder.setTenantId(CommonConstants.SYSTEM_TENANT_ID);
				SysConfigSmsTemplates sysConfigSmsTemplates = this.getSysConfigSmsTemplates(smsConfigProperties);
				//6、租户入驻手机号码验证码
				signName = sysConfigSmsTemplates.getSignName9();
				templateCode = sysConfigSmsTemplates.getTemplateCode9();
			}
		}

		String key = CacheConstants.VER_CODE_DEFAULT + type + ":" + phone;
		Long seconds = redisTemplate.opsForValue().getOperations().getExpire(key);

		if (seconds > 240) {
			log.info("验证码发送过频繁:{}", phone);
			return R.failed(Boolean.FALSE, "验证码发送过频繁，请稍后再试");
		}

		String code = RandomUtil.randomNumbers(Integer.parseInt(SecurityConstants.CODE_SIZE));
		log.debug("手机号生成验证码成功:{},{}", phone, code);
		SmsUtils.sendSms(smsConfigProperties, signName, phone, templateCode, "{\"code\":\""+code+"\"}");
		redisTemplate.opsForValue().set(key, code, SecurityConstants.CODE_TIME, TimeUnit.SECONDS);
		return R.ok(Boolean.TRUE);
	}

	SysConfigSmsTemplates getSysConfigSmsTemplates(SmsConfigProperties smsConfigProperties) throws Exception {
		SysConfigSms sysConfigSms = sysConfigSmsService.getOne();
		if(sysConfigSms == null){
			throw new RuntimeException("未配置短信账号，租户ID：" + TenantContextHolder.getTenantId());
		}
		BeanUtil.copyProperties(sysConfigSms, smsConfigProperties);
		return JSONUtil.toBean(sysConfigSms.getTemplates(),SysConfigSmsTemplates.class);
	}
}
